﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Common.DataStructures;

namespace Boggle
{
    public class BoggleSolver : IBoggleSolver
    {
        private readonly IBoggleDictionary _boggleDictionary;

        public BoggleSolver(IBoggleDictionary boggleDictionary)
        {
            _boggleDictionary = boggleDictionary;
        }

        public IEnumerable<BoggleTraversal> Solve(BoggleBoard board)
        {
            Queue<BoggleTraversal> traversalQueue = new Queue<BoggleTraversal>();
            foreach (int row in Enumerable.Range(0, board.Height))
            {
                foreach (int column in Enumerable.Range(0, board.Width))
                {
                    BoggleTraversal traversal = new BoggleTraversal();
                    traversal.Visit(board[row, column]);
                    traversalQueue.Enqueue(traversal);
                }
            }

            LinkedList<BoggleTraversal> solutions = new LinkedList<BoggleTraversal>();
            while (traversalQueue.Count > 0)
            {
                BoggleTraversal traversal = traversalQueue.Dequeue();
                String traversalWord = traversal.ToString();
                SearchResult searchResult = _boggleDictionary.Search(traversalWord);
                //if there was a full match and the word is more than 3 letters
                if (searchResult == SearchResult.FullMatch && traversalWord.Length > 3)
                {
                    //add the traversal to the list of solutions
                    solutions.AddLast(traversal);
                }
                //if there was a full or partial match then create new traversal with each neighbor
                if (searchResult == SearchResult.FullMatch || searchResult == SearchResult.PartialMatch)
                {
                    //create new traversal with neighbors
                    BoggleCell traversalCurrentCell = traversal.CurrentCell;
                    IEnumerable<BoggleCell> neighbors = board.GetNeighbors(traversalCurrentCell.Row, traversalCurrentCell.Column);
                    foreach (BoggleCell neighbor in neighbors)
                    {
                        if (traversal.HasVisited(neighbor) == false)
                        {
                            BoggleTraversal newTraversal = new BoggleTraversal(traversal);
                            newTraversal.Visit(neighbor);
                            traversalQueue.Enqueue(newTraversal);
                        }
                    }
                }
            }
            return solutions;
        }
    }

    

}
